package com.fast.develop.integration.orm;

import cn.hutool.core.bean.BeanUtil;
import com.fast.develop.integration.orm.id.IdentifierSetter;
import com.fast.develop.integration.orm.id.MetaDomainModelsVisit;
import com.fast.develop.integration.orm.resolver.FieldTypeResolver;
import com.fast.develop.meta.dm.MetaDomainModel;
import org.hibernate.Session;
import org.hibernate.Transaction;

import java.io.Serializable;
import java.util.Map;

/**
 * @author 莫寅
 * @createTime 2022-06-23 03:11
 * @desc：
 */
public class MapDomainModelSessionManager extends AbstractDomainModelSessionManager {

    private Session session;
    private FieldTypeResolver fileTypeResolver;
    private IdentifierSetter identifierSetter;
    private MetaDomainModelsVisit metaDomainModelsVisit;

    public MapDomainModelSessionManager(Session session, FieldTypeResolver fileTypeResolver, IdentifierSetter identifierSetter, MetaDomainModelsVisit metaDomainModelsVisit) {
        super(session);
        this.session = session;
        this.fileTypeResolver = fileTypeResolver;
        this.identifierSetter = identifierSetter;
        this.metaDomainModelsVisit = metaDomainModelsVisit;
    }

    /**
     * 新增前处理
     */
    private void beforeCreateHandle(String model, Object object){
        //是否元模型，不是则直接返回，不处理
        if(!isMetaModel(model)){
            return ;
        }
        //解析字段类型，进行处理
        fileTypeResolver.resolve(model, (Map) object);
        //设置ID
        identifierSetter.setId(model, (Map) object);
    }

    /**
     * 新增前处理
     */
    private void beforeUpdateHandle(String model, Object object){
        //是否元模型，不是则直接返回，不处理
        if(!isMetaModel(model)){
            return ;
        }
        //解析字段类型，进行处理
        fileTypeResolver.resolve(model, (Map) object);

    }

    /**
     * 是否元模型
     * @return
     */
    private boolean isMetaModel(String model){
        MetaDomainModel metaDomainModel = metaDomainModelsVisit.getMeta(model);
        if(metaDomainModel != null){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public Serializable create(String model, Object object){
        beforeCreateHandle(model, object);
//        AbstractEntityPersister abstractEntityPersister = (AbstractEntityPersister) ((EventSource)session).getEntityPersister(model, object);
//        SqlStringUtil.getSQLInsertStrings(abstractEntityPersister);
        Transaction transaction = session.beginTransaction();
        try{

            Serializable serializable = session.save(model, object);
            transaction.commit();
            return serializable;
        }catch (Exception e){
            transaction.rollback();
            throw e;
        }
    }


    @Override
    public void update(String model, Serializable id, Object object){
        Map map = (Map)object;
        //解析字段类型，进行处理
        beforeUpdateHandle(model, map);


        Transaction transaction = session.beginTransaction();
        String idName = idName(model);
        try{
            map.put(idName, id);
            Map obj = (Map) session.get(model, id);

            Map mergeData = BeanUtil.beanToMap(map, obj, false, true);
            session.update(model, mergeData);

            transaction.commit();
        }catch (Exception e){
            transaction.rollback();
            throw e;
        }
    }



    @Override
    protected String idName(String meta){
        return metaDomainModelsVisit.getIdentifierProperty(meta).getName();
    }
}
